<?php
/**
 * 
 * @author bqd
 *
 */

class ExtendedConfigurationBehavior extends ModelBehavior {
	var $options = array();
	
    function setup(&$model, $settings = array()) {
        $default = array(
        	'configFolder'		=>	$model->alias,
			'cacheName'		=> 'default_configurations',
			'reloadConfig'		=>	true,
			'names'		=> array('Themes', 'Cache', $model->alias),
			'overrides'	=>	array(),
			'noCache'	=>	false
		);
		
		ExtendedConfigurationBehavior::fillSetting($settings);
		if (!isset($this->__settings[$model->alias])) {
			$this->__settings[$model->alias] = $default;
		}
		$this->modelName = $model->alias;
		$this->__settings[$model->alias] = am($this->__settings[$model->alias], $settings);
		
    }
	
	function fillSetting(&$settings) {
		if (!isset($settings['cacheName'])) {
			if (isset($settings['configFolder'])) {
				$settings['cacheName'] = "{$settings['configFolder']}_configs";
				$settings['configFilename'] = 'config';
			} else if (isset($settings['configFilename'])) {
				$settings['configFolder'] = '';
				$settings['cacheName'] = str_replace(".", "_", $settings['configFilename'])."_configs";
			} else {
				throw new Exception(__("Config folder and config filename can't be both left empty", true));
			}
		}
		if (!isset($settings['overrides'])) {
			$settings['overrides'] = array();
		}
	}
	
	function __loadConfig(&$settings = array()) {
		ExtendedConfigurationBehavior::fillSetting($settings);
		
		// Make sure Themes and Cache always be read
		$sections = array('Themes', 'Cache');
		
		foreach ($sections as $section) {
			if (!in_array($sections, $settings['names'])) {
				$settings['names'][] = $section;
			}
		}
		
		// Reading Info
		$configs = array();
		
		if (!isset($_GET['resetConfig']) && !(isset($settings['reloadConfig']) && $settings['reloadConfig'])) {
			// Load config files from tmp/cache/persistent folder
			$loaded = Configure::load($settings['cacheName']);
		
			if ($loaded !== false) {
				foreach ($settings['names'] as $config_name) {
					$config = Configure::read($config_name);
					if (is_array($config)) {
						$configs[$config_name] = $config;
					}
				}
			}
		}
		
		// if not exists, load configuration default from config folder
		if (empty($configs) || isset($_GET['resetConfig']) || (isset($settings['reloadConfig']) && $settings['reloadConfig'])) {
			// Delete Configure Files before store to prevent appendtion

			$oldDebug = Configure::read('debug');
			Configure::write('debug',1);
			
			if (isset($settings['configFilename'])) {
				if (isset($settings['plugin'])) {
					$loaded = Configure::load($settings['plugin'] . '.' . $settings['configFilename']);
				} else {
					$loaded = Configure::load($settings['configFilename']);
				}
			} else {
				$loaded = Configure::load($settings['configFolder'].'/config');
			}

			// Reading Info
			$configs = array();
			foreach ($settings['names'] as $config_name) {
				
				$config = Configure::read($config_name);
				if (is_array($config)) {
					$configs[$config_name] = $config;
					
					// Save default configuration to tmp/cache/persistent folder
					if ((!isset($settings['noCache']) || $settings['noCache'] == false) && (!isset($settings['reloadConfig']) || !$settings['reloadConfig'])) {
						Configure::store($config_name,$settings['cacheName'], $config);
					}
				}
			}
			Configure::write('debug', $oldDebug);
		}
		
		$configs['names'] = $settings['names'];
		
		$configs['metadata'] = array(
			'configFolder'		=> $settings['configFolder'],
			'cacheName'		=> $settings['cacheName']
		);
		
		if (isset($settings['merge']) && is_array($settings['merge'])) {
			//debug($configs);exit;
			foreach ($settings['merge'] as $item) {
				// disable cache in this case
				//$item['settings']['noCache'] = true;
				$merge_configs = $this->__loadConfig($item['settings']);

				$configs = $this->__merge($merge_configs, $configs, $item['settings']);
			}
		}
		
		// Check Cache
		if (!isset($configs['Cache'])) {
			$configs['Cache']['cacheName'] = $settings['cacheName'];
		}
		return $configs;
	}
	/**
	 * Phương thức được sử dụng để load config của Model
	 * @return unknown_type
	 */
	function loadConfig(&$model, $settings = array()) {
		
		if (!count($settings)) {
			$settings = $this->__settings[$model->alias];
		} else {
			
			if (!isset($this->__settings) || !isset($this->__settings[$model->alias])) {
				ExtendedConfigurationBehavior::setup($model, $settings);
			}
			$settings = am($this->__settings[$model->alias], $settings);

		}
		
		$configs = $this->__loadConfig($settings);
		return $configs;
	}
	
	function __merge($old_configs, $new_configs, $settings) {
		foreach ($settings['overrides'] as $key => $override) {
			if (isset($old_configs[$key])) {
				$old_configs[$override] = $old_configs[$key];
				unset($old_configs[$key]);
			}
		}
		
		// Merge configs
		foreach ($new_configs as $key => $config) {
			// Nếu tồn tại config cũ
			if (isset($old_configs[$key])) {
				foreach ($new_configs[$key] as $child_key => $config_value) {
					$old_configs[$key][$child_key] = $config_value;
				}
			} else {
				$old_configs['names'][] = $key;
				$old_configs[$key] = $config;
			}
		}
	
		$old_configs['metadata'] = array(
			'configFolder'		=>	$settings['configFolder'],
			'configFilename'	=>	$settings['configFilename'],
			'cacheName'			=>	$settings['cacheName']
		);
		return $old_configs;
	}
	function mergeConfig(&$model, $old_configs, $settings) {
		$this->fillSetting($settings);
		
		$sections = array('Themes', 'Cache');
		
		foreach ($sections as $section) {
			if (!in_array($sections, $settings['names'])) {
				$settings['names'][] = $section;
			}
		}
		
		$new_configs = $this->loadConfig($model, $settings);
		
		$new_configs = $this->__merge($old_configs, $new_configs, $settings);
		return $new_configs;
	}
	function __singleConfigToMultiple($config) {
		
		$name = $config['names'][0];
		$tmp = $config;
		unset($config);
		
		$config[$name] = $tmp;
		$config['names'] = $config[$name]['names'];
		$config['metadata'] = $config[$name]['metadata'];
		
		unset($config[$name]['names']);
		return $config;
	}
}
?>